package com.xingchi.tornado.dict.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xingchi.tornado.basic.ErrorCode;
import com.xingchi.tornado.core.context.SpringContextHolder;
import com.xingchi.tornado.core.enums.OperateTypeEnum;
import com.xingchi.tornado.dict.event.DictDataChangeEvent;
import com.xingchi.tornado.dict.mapper.DictGroupMapper;
import com.xingchi.tornado.dict.model.domain.DictGroupDO;
import com.xingchi.tornado.dict.model.dto.DictGroupAddDTO;
import com.xingchi.tornado.dict.model.dto.DictGroupDTO;
import com.xingchi.tornado.dict.model.dto.DictGroupEditDTO;
import com.xingchi.tornado.dict.model.dto.DictGroupQueryDTO;
import com.xingchi.tornado.dict.service.DictGroupService;
import com.xingchi.tornado.dict.service.DictItemService;
import com.xingchi.tornado.exception.BizException;
import com.xingchi.tornado.mybatisplus.service.AbstractBasePlusService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xingchi
 * @date 2025-05-27 15:24
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DictGroupServiceImpl extends AbstractBasePlusService<DictGroupMapper, DictGroupDTO, DictGroupQueryDTO, DictGroupDO> implements DictGroupService {

    @Autowired
    @Lazy
    private DictItemService dictItemService;

    @Override
    public Wrapper<DictGroupDO> getWrapper(DictGroupQueryDTO query) {
        return Wrappers.<DictGroupDO>lambdaQuery()
                .eq(StringUtils.isNotBlank(query.getCode()), DictGroupDO::getCode, query.getCode())
                .eq(Objects.nonNull(query.getSource()), DictGroupDO::getSource, query.getSource())
                .like(StringUtils.isNotBlank(query.getSearchName()), DictGroupDO::getName, query.getSearchName())
                .like(StringUtils.isNotBlank(query.getSearchCode()), DictGroupDO::getCode, query.getSearchCode())
                .in(CollectionUtils.isNotEmpty(query.getCodeList()), DictGroupDO::getCode, query.getCodeList())
                .orderByAsc(BooleanUtils.isTrue(query.getOrderBySort()), DictGroupDO::getSort);
    }

    /**
     * 添加字典分组
     *
     * @param dictGroup 字典分组添加信息
     * @return 分组id
     */
    @Override
    public Long addGroup(DictGroupAddDTO dictGroup) {
        DictGroupDTO dictGroupDTO = DictGroupDTO.builder()
                .code(dictGroup.getCode())
                .name(dictGroup.getName())
                .desc(dictGroup.getDesc())
                .sort(dictGroup.getSort())
                .source(dictGroup.getSource())
                .build();

        DictGroupDTO group = this.insert(dictGroupDTO);
        SpringContextHolder.publishEvent(new DictDataChangeEvent(group.getCode(), OperateTypeEnum.INSERT));
        return group.getId();
    }

    /**
     * 更新字典信息
     *
     * @param updateDictGroup 字典分组信息
     * @return 分组id
     */
    @Override
    public Boolean updateGroup(DictGroupEditDTO updateDictGroup) {

        DictGroupDTO dbDictGroup = this.selectById(updateDictGroup.getId());
        BizException.throwIf(dbDictGroup == null, ErrorCode.DATA_NOT_FOUND, "字典分组不存在");

        DictGroupDTO group = DictGroupDTO.builder()
                .id(updateDictGroup.getId())
                .code(updateDictGroup.getCode())
                .name(updateDictGroup.getName())
                .desc(updateDictGroup.getDesc())
                .sort(updateDictGroup.getSort())
                .source(updateDictGroup.getSource())
                .build();
        this.updateById(group);
        if (!dbDictGroup.getCode().equals(updateDictGroup.getCode())) {
            // 两个不相等则修改枚举项中的code
            dictItemService.updateGroupCode(dbDictGroup.getCode(), updateDictGroup.getCode());
        }

        SpringContextHolder.publishEvent(new DictDataChangeEvent(group.getCode(), OperateTypeEnum.UPDATE));

        return true;
    }

    /**
     * 删除字典分组
     *
     * @param id 分组id
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteGroup(Long id) {

        // 删除字典项
        DictGroupDTO dictGroupDTO = this.selectById(id);
        BizException.throwIf(dictGroupDTO == null, ErrorCode.DATA_NOT_FOUND, "字典分组不存在");

        dictItemService.deleteByGroupCode(dictGroupDTO.getCode());
        Boolean status = deleteById(id);
        if (status) {
            SpringContextHolder.publishEvent(new DictDataChangeEvent(dictGroupDTO.getCode(), OperateTypeEnum.DELETE));
        }
        return status;
    }

    @Override
    public Boolean deleteByGroupCode(List<String> groupCodes) {
        return this.remove(Wrappers.<DictGroupDO>lambdaQuery().in(DictGroupDO::getCode, groupCodes));
    }
}
